/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.easoftware.code.dao;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import javax.ejb.EJB;
import javax.inject.Inject;
import javax.inject.Named;
import net.easoftware.code.beans.JpaEntityConverter;
import net.easoftware.code.beans.QueryParameter;
import net.easoftware.code.beans.cargas.threading.CargasSavingThread;
import net.easoftware.code.beans.facade.CargaDatosFc;
import net.easoftware.code.beans.jpa.Cargadatos;
import net.easoftware.code.error.EaError;
import net.easoftware.code.util.Constantes;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.log4j.Logger;

/**
 *
 * @author EADeveloper
 */
@Named("cargasDao")
public class CargasDao implements Serializable {

    private static final Logger logger = Logger.getLogger(CargasDao.class.getName());
    @EJB
    PersistenceEjb ejb;
    @Inject
    DSManager dsManager;

    /**
     *
     * @param tipoValidacion
     * @throws EaError
     */
    public void validarDatosCarga(String tipoValidacion) throws EaError {
        try {
            QueryRunner qr = new QueryRunner(dsManager.getDs());
            switch (tipoValidacion) {
                case "AsOff":
                    qr.update("CALL procesarAsOff();");
                case "ChequeRechazadoCA":
                    qr.update("CALL procesarChequesRechazados();");
                case "OrdenCA":
                    qr.update("CALL procesarOrdenes();");
                case "OrdenRetenidaCA":
                    qr.update("CALL procesarOrdenesRet();");
                case "VentaCA":
                    qr.update("CALL procesarVentas();");
            }
        }
        catch (SQLException ex) {
            throw new EaError("Error al obtener el grid principal", ex);
        }
    }

    /**
     *
     * @throws EaError
     */
    public void deleteDatosInvalidos() throws EaError {
        try {
            QueryRunner qr = new QueryRunner(dsManager.getDs());
            qr.update("CALL deleteCargasMIDatosInvalidos();");
        }
        catch (SQLException ex) {
            throw new EaError("Error al obtener el grid principal", ex);
        }
    }

    /**
     *
     * @param cargaDatos
     * @return
     * @throws EaError
     */
    public boolean guardarCargaDatos(CargaDatosFc cargaDatos, boolean append) throws EaError {
        try {
            Cargadatos cd = null;
            if (cargaDatos.getCargaDatos().getCargaExistente() != null) {
                if (!append) {
                    ejb.eliminar(cargaDatos.getCargaDatos().getCargaExistente());
                } else {
                    cd = cargaDatos.getCargaDatos().getCargaExistente();
                }
            } else {
                cd = (Cargadatos) ejb.guardar(cargaDatos.getEntityBean());
            }
            int totalRows = cargaDatos.getCargaDatos().getData().size();
            List rowsThread = new LinkedList();
            int c = 0;
            for (Object fila : cargaDatos.getCargaDatos().getData()) {
                c++;
                if (fila instanceof JpaEntityConverter) {
                    try {
                        Object e = ((JpaEntityConverter) fila).getEntityBean();
                        Method m = e.getClass().getMethod("setCargadatos", Cargadatos.class);
                        m.invoke(e, cd);

                        rowsThread.add(e);
                    }
                    catch (EaError | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
                        logger.error(ex);
                    }
                    if (rowsThread.size() == Constantes.LOAD_SIZE_ON_SAVING
                            || c == totalRows) {
                        CargasSavingThread hilo = new CargasSavingThread(ejb, dsManager, new LinkedList(rowsThread), cargaDatos.getHilos().size() + 1);
                        cargaDatos.getHilos().add(hilo);
                        Thread th = new Thread(hilo);
                        th.start();
                        rowsThread = new LinkedList();
                    }
                }
            }
            return true;
        }
        catch (Exception ex) {
            throw new EaError("Problema al guardar datos archivo ASOFF", ex);
        }
    }

    /**
     *
     * @param mes
     * @param anio
     * @param store
     * @return
     */
    public Cargadatos existeCarga(Integer mes, Integer anio, Class store) {
        try {
            List<Cargadatos> c = (List<Cargadatos>) ejb.doJPAQuery("select c from Cargadatos c where c.mes=:mess and c.anio=:anio",
                    new QueryParameter[]{
                new QueryParameter("mess", mes),
                new QueryParameter("anio", anio)
            }, PersistenceEjb.LIST);
            Object val = store.newInstance();
            if (val instanceof JpaEntityConverter && c != null && !c.isEmpty()) {
                for (Cargadatos cd : c) {
                    Class findType = ((JpaEntityConverter) val).getDestClassType();
                    if (findType != null) {
                        Number r = (Number) ejb.doJPAQuery("select count(c) from " + findType.getSimpleName() + " c where c.cargadatos.id=:cargaid",
                                new QueryParameter[]{
                            new QueryParameter("cargaid", cd.getId())
                        }, PersistenceEjb.SINGLE);
                        if (r != null && r.intValue() > 0) {
                            return cd;
                        }
                    }
                }
            }


        }
        catch (InstantiationException | IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(CargasDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     *
     * @param carga
     */
    public void eliminarCarga(CargaDatosFc carga) {
        ejb.eliminar(this);
    }

    public void eliminarCarga(Integer id) {
        Cargadatos cg = (Cargadatos) ejb.doNamedQuery("Cargadatos.findById", new QueryParameter[]{new QueryParameter("id", id)}, PersistenceEjb.SINGLE);
        ejb.eliminar(cg);
    }
}
